import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author sk.z
 */
public class WanIp {

    private static List<String> WEBSITE_LIST;
    private static int INDEX = 0;

    private static final Pattern IP_PATTERN = Pattern.compile("(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])");

    public static void init(List<String> webSiteList) throws InterruptedException {
        if (Objects.isNull(webSiteList)||webSiteList.isEmpty()){
            System.out.println("no config website");
            Thread.sleep(3000);
            System.exit(0);
        }
        WEBSITE_LIST = new ArrayList<>(webSiteList.size());
        WEBSITE_LIST.addAll(webSiteList);
    }

    public static String get() {
        if (INDEX >= WEBSITE_LIST.size()) {
            INDEX = 0;
        }
        String site = WEBSITE_LIST.get(INDEX);
        INDEX++;

        String content = httpGetIp(site);
        if (Objects.isNull(content)) {
            return null;
        } else {
            return content;
        }

    }

    public static void showSite() {
        System.out.println("\nvalid website list :");
        for (String site : WEBSITE_LIST) {
            System.out.println("\t" + site);
        }
    }

    public static String check() throws InterruptedException {
        System.out.println("\ncheck all website :");
        //遍历获取外网ip
        List<String> valueList = new ArrayList<>(WEBSITE_LIST.size());
        for (String site : WEBSITE_LIST) {
            String value = httpGetIp(site);
            System.out.println("\t"+site + " >> " + value);
            if (Objects.isNull(value)) {
                valueList.add("null");
            } else {
                valueList.add(value);
            }
        }

        //统计获取多数作为正确的ip地址
        Map<String, Integer> countMap = new HashMap<>();
        for (String key : valueList) {
            if (key.equals("null")) {
                continue;
            }
            if (!countMap.containsKey(key)) {
                countMap.put(key, 1);
            }
            countMap.put(key, countMap.get(key) + 1);
        }
        String rightValue = null;
        int rightNum = 0;
        for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
            if (entry.getValue() > rightNum) {
                rightValue = entry.getKey();
                rightNum = entry.getValue();
            }
        }

        if (Objects.isNull(rightValue)) {
            System.out.println("no available website get Wan Ip");
            Thread.sleep(3000);
            System.exit(0);
        }

        //删除错误的网址
        for (int i = WEBSITE_LIST.size() - 1; i >= 0; i--) {
            if (!valueList.get(i).equals(rightValue)){
                System.out.println("\t\t"+WEBSITE_LIST.get(i)+" is error , remove it .");
                WEBSITE_LIST.remove(i);
            }
        }

        return rightValue;
    }

    private static String httpGetIp(String urlStr) {
        BufferedReader reader = null;
        try {
            URL url = new URL(urlStr);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setConnectTimeout(10000);
            urlConnection.setReadTimeout(5000);

            int responseCode = urlConnection.getResponseCode();
            if (responseCode != 200) {
                System.out.println("connect [" + urlStr + "] : " + responseCode + " " + urlConnection.getResponseMessage());
                return null;
            }

            reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            String read;
            while ((read = reader.readLine()) != null) {
                Matcher matcher = IP_PATTERN.matcher(read);
                if (matcher.find()) {
                    return matcher.group(1) + "." + matcher.group(2) + "." + matcher.group(3) + "." + matcher.group(4);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException ignored) {
                }
            }
        }
        return null;
    }

}
